// clone/deepclone
// create/new/instanceof
// get/memorized


function deepClone(obj, map= new Map()){
    if(obj instanceof RegExp){
        return new RegExp(obj)
    }
    if(obj instanceof Date){
        return new Date(obj)
    }
    if(typeof obj !== 'object' || obj === null){
        return obj
    }
    let Constructor = obj.constructor;
    let res = new Constructor();
    if(map.has(res)){
        return map.get(res)
    }
    map.set(obj, res)
    Object.keys(obj).forEach((key) => {
        if(obj.hasOwnProperty(key)){
            res[key] = deepClone(obj[key], map)
        }
    })
    return res;

}
// 示例使用
const original = {
    number: 1,
    bool: false,
    string: 'string',
    date: new Date(),
    regex: /regex/,
    array: [1, 2, 3],
    object: {
        nested: 'nested'
    },
    func: function () { console.log('hello'); }
};
const copied = deepClone(original);
console.log(copied);


function create(obj){
    function fn(){};
    fn.prototype = obj;
    return new fn()
}

function mynew(fn, ...args){
    let newFn = Object.create(fn.prototype);
    let res = fn.call(newFn, ...args)
    return res instanceof Object ? res : newFn
}

function myInstanceOf(obj, Obj){
    let objProto = obj.__proto__
    let ObjProto = Obj.prototype;

    while(true){
        if(objProto === null){
            return false
        }
        if(objProto === ObjProto){
            return true
        }
        objProto = objProto.__proto__
    }
}
// 示例
function A() { }
let a = new A();

console.log(myInstanceOf(a, A), '---'); // true
console.log(myInstanceOf(a, Object)); // true
console.log(myInstanceOf(a, Array)); // false


function get(obj, path, defaultValue){
    if(!Array.isArray(path)){
        let regex = /[^\[\].]+/g
        path = path.match(regex)
    }

    for(let i = 0; i< path.length; i++){
        if(!obj) return defaultValue
        obj = obj[path[i]]
    }
    return obj === undefined ? defaultValue : obj

}
const obj = {a:[{b: {c: 3}}]}
console.log(get(obj, ['a','0','b', 'c'], 9))
console.log(get(obj, "a[0].b.c", 9))
